#pragma once
#include <pthread.h>
#include <semaphore.h>
#include <iostream>
#include <unistd.h>
#include "Sem.hpp"
#include "Mutex.hpp"
#include <vector>
#include <string>

namespace MyRingQueueModule
{
    using namespace MpthreayMutex;
    using namespace MySemModule;
    template <class T>
    class ringqueue
    {
    public:
        ringqueue(int cap)
            : _cap(cap),
              space_sem(cap),
              data_sem(0),
              c_step(0),
              p_step(0),
              _rq(cap)
        {
        }
        void Equeue(T &in)
        {
            space_sem.P();
            {
                LockGround lockground(pro_mtx);   
                _rq[p_step++] = in;
                p_step %= _cap;
            }
            data_sem.V();
        }
        void Pop(T *out)
        {
            data_sem.P();
            {
                LockGround lockground(cus_mtx);
                printf("###########################\n");
                printf("消费者走到这了: %d, 接受的是: %s\n", c_step,_rq[c_step].Name().c_str());
                printf("###########################\n");
                *out = _rq[c_step++];
                c_step %= _cap;
            }
            space_sem.V();
        }
        ~ringqueue()
        {
        }

    private:
        std::vector<T> _rq;
        int _cap;
        Sem space_sem;
        Sem data_sem;
        Mutex pro_mtx;
        Mutex cus_mtx;
        int c_step;
        int p_step;
    };
}
